package com.k7.mobile.platform.web.interceptor;

import java.io.Serializable;
import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.log4j.Logger;

import com.k7.mobile.platform.bo.IJedisBO;
import com.k7.mobile.platform.bo.IMemCacheBO;
import com.k7.mobile.platform.dataobject.BaseDO;
import com.k7.mobile.platform.web.support.RedisConstants;

public class MethodCacheInterceptor implements MethodInterceptor {
 
    private static final Logger log = Logger.getLogger(MethodCacheInterceptor.class);
    
    private IMemCacheBO memCacheBO;
 
	public void setMemCacheBO(IMemCacheBO memCacheBO) {
		this.memCacheBO = memCacheBO;
	}

	public Object invoke(MethodInvocation invocation) throws Throwable {
        String targetName = invocation.getThis().getClass().getName();
        String methodName = invocation.getMethod().getName();
        Object[] arguments = invocation.getArguments();
        Object result = null;
 
        String cacheKey = getCacheKey(targetName, methodName, arguments);
       // Object element = null;
        //synchronized (this) {
        Object  element = memCacheBO.get(cacheKey);
            if (element == null) {
                log.info(cacheKey + "加入到缓存： Redis");
                // 调用实际的方法
                result = invocation.proceed();
                //element = new Element(cacheKey, (Serializable) result);
                memCacheBO.set(cacheKey,(Serializable)result,RedisConstants.DEFAULT_CACHE_EXPIRED_TIME);
            } else {
                log.info(cacheKey + "使用缓存： Redis");
            }
       // }
        return result;
    }
 
    /**
     * <b>function:</b> 返回具体的方法全路径名称 参数
     * @author hoojo
     * @createDate 2012-7-2 下午06:12:39
     * @param targetName 全路径
     * @param methodName 方法名称
     * @param arguments 参数
     * @return 完整方法名称
     */
    private String getCacheKey(String targetName, String methodName, Object[] arguments) {
        StringBuffer sb = new StringBuffer();
        sb.append(targetName.substring(targetName.lastIndexOf(".")+1)).append(RedisConstants.DEFAULT_CACHE_FIELD_SEPARATOR).append(methodName);
        if ((arguments != null) && (arguments.length != 0)) {
            for (int i = 0; i < arguments.length; i++) {
            	String argumentsName = arguments[i].getClass().getCanonicalName();
                sb.append(RedisConstants.DEFAULT_CACHE_FIELD_SEPARATOR).append(argumentsName.substring(argumentsName.lastIndexOf(".")+1));
                if(arguments[i] instanceof BaseDO){
                	try{
                	Method genKeyMethod =arguments[i].getClass().getDeclaredMethod("genCacheKey");
                	String key = (String)genKeyMethod.invoke(arguments[i]);
                	sb.append(RedisConstants.DEFAULT_CACHE_FIELD_SEPARATOR).append(key);
                	}catch(Exception e){
                		log.error(e);
                	}
                }
            }
        }
        return sb.toString();
    }
}
